package com.airbat.prize.utils;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.util.GeometricShapeFactory;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class GeometryUtil {

    private static GeometryFactory geometryFactory = new GeometryFactory();
    private static GeometricShapeFactory shapeFactory = new GeometricShapeFactory();

    //地球赤道周长
    private static final double P_EARTH = 40075017;
    //圆形边数
    private static final int SIDES = 64;
    /**
     * 创建一个圆
     * 用环形闭合线绘制的多边形表示圆
     * @param x 中心点x
     * @param y 中心点y
     * @param radiusMile 半径 米
     */
    public static Polygon createCircle(double x, double y, final double radiusMile) {
        //半径转度数
        double radiusLat = parseRadiusToDegree(radiusMile);

        //类圆形的边数
        shapeFactory.setNumPoints(SIDES);
        //中心点
        shapeFactory.setCentre(new Coordinate(x, y));
        //直径
        shapeFactory.setSize(radiusLat * 2);
        return shapeFactory.createCircle();
    }

    /**
     * 将Y轴的长度（米）转换成纬度
     * @param radiusMile 半径
     */
    public static double parseRadiusToDegree(double radiusMile){
        //半径转度数
        return radiusMile / P_EARTH * 360;
    }

    /**
     * 根据区域坐标字符串创建多边形
     * @param scopeString 区域坐标字符串，@example{120.0,27.0...}
     */
    public static Geometry createGeometry(String scopeString) {
        if (StringUtils.isBlank(scopeString)) {
            return null;
        }
        Geometry geometry;
        List<Double> list = Arrays.stream(scopeString.split(",")).map(Double::valueOf).collect(Collectors.toList());
        if (list.size() == 3) {
            //圆形
            geometry = createCircle(list.get(0), list.get(1), list.get(2));
        } else {
            //多边形
            int size = list.size() / 2;
            Coordinate[] pointList = new Coordinate[size+1];
            for (int i = 0; i < size; i++) {
                Coordinate coordinate = new Coordinate(list.get(i*2), list.get(i*2 + 1));
                pointList[i] = coordinate;
            }
            //闭合
            pointList[size] = pointList[0];
            geometry = geometryFactory.createPolygon(pointList);
        }
        return geometry;
    }

    /**
     * 根据区域坐标字符串创建多边形
     * @param bound 边界坐标点
     */
    public static Geometry createGeometry(Bound bound) {
        if (bound.getMaxLng() == null || bound.getMaxLat() == null || bound.getMinLat() == null || bound.getMinLng() == null) {
            return null;
        }
        Geometry geometry;
        //多边形
        Coordinate[] pointList = new Coordinate[5];
        pointList[0] = new Coordinate(bound.getMaxLng(), bound.getMaxLat());
        pointList[1] = new Coordinate(bound.getMaxLng(), bound.getMinLat());
        pointList[2] = new Coordinate(bound.getMinLng(), bound.getMinLat());
        pointList[3] = new Coordinate(bound.getMinLng(), bound.getMaxLat());
        //闭合
        pointList[4] = pointList[0];
        geometry = geometryFactory.createPolygon(pointList);
        return geometry;
    }

    /**
     * 创建点位
     * @param x 经度
     * @param y 纬度
     */
    public static Point createPoint(double x, double y) {
        return geometryFactory.createPoint(new Coordinate(x, y));
    }

    @Data
    public static class Bound {
        @ApiModelProperty("最大经度")
        private Double maxLng;
        @ApiModelProperty("最小经度")
        private Double minLng;
        @ApiModelProperty("最大纬度")
        private Double maxLat;
        @ApiModelProperty("最小纬度")
        private Double minLat;
    }
}
